package com.ouc.service.impl;

import com.ouc.common.core.domain.R;
import com.ouc.common.utils.ToPictureUtil;
import com.ouc.dao.NavigationDao;
import com.ouc.domain.*;
import com.ouc.oceanBase.service.NcPictService;
import com.ouc.service.NavigationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.DoubleBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

@Service
public class NavigationServiceImpl implements NavigationService {

  @Autowired
  private NavigationDao navigationDao;

  @Autowired
  private NcPictService ncPictService;

  @Override
  public int creatPre(PreFile preFile) {
    return navigationDao.creatPre(preFile);
  }

  @Override
  public String runPre(String preDir) {
    return navigationDao.runPre(preDir);
  }

  @Override
  public PreFile getPreResult(PreFile preFile) {
    return navigationDao.getPreResult(preFile);
  }

  @Override
  public PreFile getPreWaFile(PreFile preFile) {
    return navigationDao.getPreWaFile(preFile);
  }

  @Override
  public int creatMain(MainFile mainFile) {
    return navigationDao.creatMain(mainFile);
  }

  @Override
  public String runMain(String mainDir) {
    return navigationDao.runMain(mainDir);
  }

  @Override
  public MainOutFile getMainOutFile(String fileDir, String jobName) {
    return navigationDao.getMainOutFile(fileDir, jobName);
  }

  @Override
  public String creatMapInFile(MainOutFile mainOutFile) {
    return navigationDao.creatMapInFile(mainOutFile);
  }

  @Override
  public int creatSpectrumSetting(SpectrumSetting spectrumSetting) {
    return navigationDao.creatSpectrumSetting(spectrumSetting);
  }

  @Override
  public String runSpectrum(String spectrumDir) {
    return navigationDao.runSpectrum(spectrumDir);
  }

  @Override
  public List<SpectrumResult> getSpectrumResult(String spectrumDir) {
    return navigationDao.getSpectrumResult(spectrumDir);
  }

  @Override
  public List<SpectrumResult> getSpectrumResultDemo(String spectrumDir, String resultFileName) {
    return navigationDao.getSpectrumResultDemo(spectrumDir, resultFileName);
  }

  @Override
  public int creatPointSafety(PointSafety pointSafety) {
    return navigationDao.creatPointSafety(pointSafety);
  }

  @Override
  public String runPointSafety(String pointSafetyDir) {
    return navigationDao.runPointSafety(pointSafetyDir);
  }

  @Override
  public PointSafety getPointSafety(String fileDir, String projectName, String projectTime) {
    return navigationDao.getPointSafety(fileDir, projectName, projectTime);
  }

  @Override
  public int creatRoteSafety(RoteSafety roteSafety) {
    return navigationDao.creatRoteSafety(roteSafety);
  }

  @Override
  public String runRoteSafety(String roteSafetyDir) {
    return navigationDao.runRoteSafety(roteSafetyDir);
  }

  @Override
  public MainOutFile getRoteSafety(String fileDir, String projectName, String projectTime) {
    return navigationDao.getRoteSafety(fileDir, projectName, projectTime);
  }

  @Override
  public Integer creatSpectrumSettingByRote(MainOutFile mainOutFile, SpectrumSetting spectrumSetting, Double shipSpeed) {
    Integer workConditionNumber = 0;
    List<Double> wh = new ArrayList<>();
    List<Double> wp = new ArrayList<>();
    List<Double> ss = new ArrayList<>();
    List<Double> wd = new ArrayList<>();
    for (ShipPathAll shipPathAll : mainOutFile.getShipPathAllList()) {
      for (ShipPathList shipPathList : shipPathAll.getShipPathLists()) {
        for (ShipPath shipPath : shipPathList.getShipPathList()) {
          wh.add(shipPath.getWaveHeight());
          wp.add(shipPath.getWavePeriod());
          ss.add(shipSpeed);
          wd.add(getWaveDirection(shipPath.getWaveDirection()));
          workConditionNumber++;
        }
      }
    }
    spectrumSetting.setWorkConditionNumber(workConditionNumber);
    spectrumSetting.setWaveHeight(wh);
    spectrumSetting.setWavePeriod(wp);
    spectrumSetting.setShipSpeed(ss);
    spectrumSetting.setWaveDirection(wd);
    navigationDao.creatSpectrumSetting(spectrumSetting);
    return workConditionNumber;
  }

  private Double getWaveDirection(Double waveDirection) {
    double wd = waveDirection - 180.0;
    if (wd < -180.0) {
      wd += 360;
    }
    if (wd > 180.0) {
      wd -= 360;
    }
    return wd;
  }

  @Override
  public Integer creatSpectrumSettingByWa(PreFile preFile, SpectrumSetting spectrumSetting, Double shipSpeed) {
    List<Double> wh = new ArrayList<>();
    List<Double> wp = new ArrayList<>();
    List<Double> ss = new ArrayList<>();
    List<Double> wd = new ArrayList<>();
    int nx = preFile.getNx();
    int ny = preFile.getNy();
    int workConditionNumber = nx * ny;
    Float[][] wdArr = preFile.getWaFile().get(0);
    for (int i = 0; i < ny; i++) {
      for (int j = 0; j < nx; j++) {
        wd.add(getWaveDirection(Double.valueOf(preFile.getWaFile().get(0)[i][j])));
        wp.add(Double.valueOf(preFile.getWaFile().get(1)[i][j]));
        wh.add(Double.valueOf(preFile.getWaFile().get(2)[i][j]));
        ss.add(shipSpeed);
      }
    }
    spectrumSetting.setWorkConditionNumber(workConditionNumber);
    spectrumSetting.setWaveHeight(wh);
    spectrumSetting.setWavePeriod(wp);
    spectrumSetting.setShipSpeed(ss);
    spectrumSetting.setWaveDirection(wd);
    navigationDao.creatSpectrumSetting(spectrumSetting);
    return workConditionNumber;
  }

  @Override
  public int creatShipParameters(RoteSafety roteSafety) {
    return navigationDao.creatShipParameters(roteSafety);
  }

  @Override
  public String runSafetyEnv(String safetyEnvDir) {
    return navigationDao.runSafetyEnv(safetyEnvDir);
  }

  @Override
  public PreFile getEnvOutFile(String filePath) {
    return navigationDao.getEnvOutFile(filePath);
  }

  @Override
  public byte[] getPngFromMainOut(MainOutFile mainOutFile) throws IOException, ExecutionException, InterruptedException {
    String[][] outMap = mainOutFile.getOutMap();
    float[][] data2D = new float[outMap.length][outMap[0].length];
    for (int i = 0; i < outMap.length; i++) {
      for (int j = 0; j < outMap[0].length; j++) {
        data2D[i][j] = Float.parseFloat(outMap[i][j]);
      }
    }
    BufferedImage bi = ncPictService.getPictFromData2DByThread(data2D, 0.0f, 1111.0f, "rainbow", false);
    return ToPictureUtil.bufferedImageToByteArray(bi);
  }

  @Override
  public byte[] getPngFromData2D(Float[][] data2D) throws IOException, ExecutionException, InterruptedException {
    float fixedMin = data2D[0][0], fixedMax = data2D[0][0];
    float[][] data = new float[data2D.length][data2D[0].length];
    for (int i = 0; i < data2D.length; i++) {
      for (int j = 0; j < data2D[0].length; j++) {
        data[i][j] = data2D[i][j];
        if (data2D[i][j] < fixedMin) {
          fixedMin = data2D[i][j];
        }
        if (data2D[i][j] > fixedMax) {
          fixedMax = data2D[i][j];
        }
      }
    }
    BufferedImage bi = ncPictService.getPictFromData2DByThread(data, fixedMin, fixedMax, "rainbow", false);
    return ToPictureUtil.bufferedImageToByteArray(bi);
  }

  @Override
  public byte[] getPngFromData2D(Double[][] data2D) throws IOException, ExecutionException, InterruptedException {
    float fixedMin = data2D[0][0].floatValue();
    float fixedMax = data2D[0][0].floatValue();
    float[][] data = new float[data2D.length][data2D[0].length];
    for (int i = 0; i < data2D.length; i++) {
      for (int j = 0; j < data2D[0].length; j++) {
        data[i][j] = data2D[i][j].floatValue();
        if (data2D[i][j] < fixedMin) {
          fixedMin = data2D[i][j].floatValue();
        }
        if (data2D[i][j] > fixedMax) {
          fixedMax = data2D[i][j].floatValue();
        }
      }
    }
    BufferedImage bi = ncPictService.getPictFromData2DByThread(data, fixedMin, fixedMax, "rainbow", false);
    return ToPictureUtil.bufferedImageToByteArray(bi);
  }
}
